package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.album.mapper.*;
import com.atguigu.tingshu.album.service.BaseCategoryService;
import com.atguigu.tingshu.model.album.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@SuppressWarnings({"all"})
public class BaseCategoryServiceImpl extends ServiceImpl<BaseCategory1Mapper, BaseCategory1> implements BaseCategoryService {

    @Autowired
    private BaseCategory1Mapper baseCategory1Mapper;

    @Autowired
    private BaseCategory2Mapper baseCategory2Mapper;

    @Autowired
    private BaseCategory3Mapper baseCategory3Mapper;

    @Autowired
    private BaseCategoryViewMapper baseCategoryViewMapper;

    @Autowired
    private BaseAttributeMapper baseAttributeMapper;


    /**
     * 查询所有分类（1、2、3级分类）
     *
     * @return
     */
    @Override
    public List<JSONObject> getBaseCategoryList() {

        //1.封装响应的集合对象，用来封装所有的一级分类数据
        List<JSONObject> list = new ArrayList<>();
        //2.查询分类视图获取所有分类视图记录
        List<BaseCategoryView> baseCategoryViewList = baseCategoryViewMapper.selectList(null);

        //3.处理一级分类数据
        if (CollectionUtil.isNotEmpty(baseCategoryViewList)) {
            //3.1 采用stream流根据一级分类id进行分组
            Map<Long, List<BaseCategoryView>> categoryMap = baseCategoryViewList
                    .stream()
                    // 根据一级分类id进行分组,在元素升级的过程中，可以使用groupingBy方法进行分组
                    .collect(Collectors.groupingBy(BaseCategoryView::getCategory1Id));

            //3.2 遍历一级分类map，创建一级分类JSONObject对象
            for (Map.Entry<Long, List<BaseCategoryView>> entry1 : categoryMap.entrySet()) {
                JSONObject jsonObject1 = new JSONObject();
                //3.2.1 封装一级分类id
                Long category1Id = entry1.getKey();
                //因为前端的字段就是categoryId，所以这里直接使用categoryId，不能使用category1Id
                jsonObject1.put("categoryId", category1Id);

                //3.2.2 封装一级分类名称
                //这个map集合中，一级分类id是key，而value是一个List<BaseCategoryView>列表
                //所以这里获取value以后，直接通过get方法，就可以得到改元素的一级分类名字。
                String category1Name = entry1.getValue().get(0).getCategory1Name();
                //同理，前端字段名称是categoryName，所以这里不能直接使用category1Name
                jsonObject1.put("categoryName", category1Name);


                //4.处理一级分类下的二级分类
                //4.1 将一级分类列表按照2级分类id进行分组，Map中key=2级分类id，value=2级分类集合
                Map<Long, List<BaseCategoryView>> category2Map = entry1.getValue()
                        .stream()
                        .collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));

                //4.2 遍历2级分类Map，创建2级分类JSONObject对象。
                List<JSONObject> jsonObject2List = new ArrayList<>();
                for (Map.Entry<Long, List<BaseCategoryView>> entry2 : category2Map.entrySet()) {
                    JSONObject jsonObject2 = new JSONObject();
                    //4.2.1 封装2级分类id
                    jsonObject2.put("categoryId", entry2.getKey());
                    //4.2.2 封装2级分类名称
                    jsonObject2.put("categoryName", entry2.getValue().get(0).getCategory2Name());
                    //为categoryChild做准备
                    jsonObject2List.add(jsonObject2);

                    //5.处理二级分类下的三级分类
                    //5.1 构建3级分类JSON集合对象
                    List<JSONObject> jsonObject3List = new ArrayList<>();

                    //5.2 遍历2级分类集合，获取3级分类集合
                    for (BaseCategoryView baseCategoryView : entry2.getValue()) {
                        JSONObject jsonObject3 = new JSONObject();
                        //5.3 封装3级分类id和名称
                        jsonObject3.put("categoryId", baseCategoryView.getCategory3Id());
                        //5.4 将3级分类集合放入2级分类对象中的categoryChild属性。
                        jsonObject3.put("categoryName", baseCategoryView.getCategory3Name());
                        jsonObject3List.add(jsonObject3);
                    }

                    jsonObject2.put("categoryChild", jsonObject3List);
                }

                //4.3 将2级分类列表放入1级分类对象的categoryChild属性中
                jsonObject1.put("categoryChild", jsonObject2List);


                //封装好分类id和分类名字后，需要将JSONObject对象添加到list集合中
                list.add(jsonObject1);
            }


        }


        return list;
    }

    /**
     * 根据一级分类Id获取分类属性以及属性值（标签名，标签值）
     *
     * @param category1Id 一级分类id
     * @return [{id:,attribute:,attributeValueList:[{id:,attributeId:,valueName:}]]
     */
    @Override
    public List<BaseAttribute> findAttributeByCategory1Id(Long category1Id) {
        return baseAttributeMapper.findAttributeByCategory1Id(category1Id);
    }

    /**
     * 根据三级分类Id 获取到分类信息
     *
     * @param category3Id
     * @return
     */
    @Override
    public BaseCategoryView getCategoryView(Long category3Id) {
        return baseCategoryViewMapper.selectById(category3Id);

    }

    /**
     * 根据一级分类Id查询7个置顶的三级分类列表
     *
     * @param category1Id
     * @return
     */
    @Override
    public List<BaseCategory3> findTop7BaseCategory3(Long category1Id) {
        //根据一级分类id查询二级分类id列表
        LambdaQueryWrapper<BaseCategory2> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseCategory2::getCategory1Id, category1Id)
                .select(BaseCategory2::getId);
        List<BaseCategory2> baseCategory2List = baseCategory2Mapper.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(baseCategory2List)) {
            List<Long> baseCategory2IdList = baseCategory2List.stream()
                    .map(BaseCategory2::getId)
                    .collect(Collectors.toList());

            //2.根据二级分类id列表查询包含的三级分类列表
            //2.1 构建查询条件
            LambdaQueryWrapper<BaseCategory3> baseCategory3LambdaQueryWrapper = new LambdaQueryWrapper<>();

            // 设置查询条件 并且设置返回个数为7 并且设置查询的列
            baseCategory3LambdaQueryWrapper
                    .in(BaseCategory3::getCategory2Id, baseCategory2IdList)
                    .eq(BaseCategory3::getIsTop, 1)
                    .orderByAsc(BaseCategory3::getOrderNum)
                    .last("limit 7")
                    .select(BaseCategory3::getId,
                            BaseCategory3::getCategory2Id,
                            BaseCategory3::getName);

            List<BaseCategory3> baseCategory3List = baseCategory3Mapper.selectList(baseCategory3LambdaQueryWrapper);
            return baseCategory3List;

        }
        return null;

    }

    /**
     * 根据一级分类id查询包含二级列表，以及二级列表下的三级分类列表
     *
     * @param category1Id
     * @return
     */
    @Override
    public JSONObject getBaseCategoryListByCategory1Id(Long category1Id) {
        //1.封装响应的对象，用来封装当前一级分类数据
        JSONObject jsonObject1 = new JSONObject();

        //2.查询分类视图获取所有分类视图记录
        LambdaQueryWrapper<BaseCategoryView> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseCategoryView::getCategory1Id, category1Id);
        List<BaseCategoryView> baseCategoryView1List = baseCategoryViewMapper.selectList(queryWrapper);

        //3.处理一级分类数据
        if (CollectionUtil.isNotEmpty(baseCategoryView1List)) {
            //3.1 获取一级分类中第一条记录得到一级分类id及名称
            BaseCategoryView baseCategoryView1 = baseCategoryView1List.get(0);

            jsonObject1.put("categoryId", baseCategoryView1.getCategory1Id());
            jsonObject1.put("categoryName", baseCategoryView1.getCategory1Name());

            //4.处理二级分类数据
            //4.2 按照二级分类id进行分组
            Map<Long, List<BaseCategoryView>> map2 = baseCategoryView1List
                    .stream()
                    .collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));

            //4.3 遍历Map封装所有二级分类集合
            List<JSONObject> jsonObject2List = new ArrayList<>();
            for (Map.Entry<Long, List<BaseCategoryView>> entry2 : map2.entrySet()) {
                Long key = entry2.getKey();
                BaseCategoryView baseCategoryView = entry2.getValue().get(0);
                //4.3.1 构建二级分类JSON对象
                JSONObject jsonObject2 = new JSONObject();
                //4.3.1 封装二级分类id及名称
                jsonObject2.put("categoryId", baseCategoryView.getCategory2Id());
                jsonObject2.put("categoryName", baseCategoryView.getCategory2Name());

                jsonObject2List.add(jsonObject2);

                //5.处理三级分类数据
                List<JSONObject> jsonObject3List = new ArrayList<>();

                for (BaseCategoryView categoryView : entry2.getValue()) {
                    //5.1 构建三级分类JSON对象
                    JSONObject jsonObject3 = new JSONObject();

                    //5.2 封装三级分类id一级名称
                    jsonObject3.put("categoryId", categoryView.getCategory3Id());
                    jsonObject3.put("categoryName", categoryView.getCategory3Name());
                    jsonObject3List.add(jsonObject3);
                }
                //注意单词问题，是child，不是chlid，这里需要注意
                //5.3 将三级分类集合放入二级分类对象中"categoryChild"
                jsonObject2.put("categoryChild", jsonObject3List);
            }

            //5.将二级分类集合放入一级分类对象中"categoryChild"
            jsonObject1.put("categoryChild", jsonObject2List);

        }

        return jsonObject1;

    }

}
